home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / nslookup / subr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-27  |  10.8 KB  |  463 lines

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)subr.c    5.12 (Berkeley) 7/23/88";
  20. #endif /* not lint */
  21.  
  22. /*
  23.  *******************************************************************************
  24.  *
  25.  *  subr.c --
  26.  *
  27.  *    Miscellaneous subroutines for the name server 
  28.  *    lookup program.
  29.  *  
  30.  *    Copyright (c) 1985 
  31.  *      Andrew Cherenson
  32.  *    U.C. Berkeley
  33.  *      CS298-26  Fall 1985
  34.  *
  35.  *******************************************************************************
  36.  */
  37.  
  38. #include <stdio.h>
  39. #include <strings.h>
  40. #include <sys/types.h>
  41. #include <netdb.h>
  42. #include <sys/socket.h>
  43. #include <netinet/in.h>
  44. #include <arpa/nameser.h>
  45. #include <signal.h>
  46. #include <setjmp.h>
  47. #include "res.h"
  48.  
  49.  
  50.  
  51. /*
  52.  *******************************************************************************
  53.  *
  54.  *  IntrHandler --
  55.  *
  56.  *    This routine is called whenever a control-C is typed. 
  57.  *    It performs three main functions:
  58.  *     - closes an open socket connection,
  59.  *     - closes an open output file (used by LookupHost, et al.),
  60.  *     - jumps back to the main read-eval loop.
  61.  *        
  62.  *    If a user types a ^C in the middle of a routine that uses a socket, 
  63.  *    the routine would not be able to close the socket. To prevent an 
  64.  *    overflow of the process's open file table, the socket and output 
  65.  *    file descriptors are closed by the interrupt handler.
  66.  *
  67.  *  Side effects:
  68.  *    If sockFD is valid, it is closed.
  69.  *    If filePtr is valid, it is closed.
  70.  *    Flow of control returns to the main() routine.
  71.  *
  72.  *******************************************************************************
  73.  */
  74.  
  75. int
  76. IntrHandler()
  77. {
  78.     extern jmp_buf env;
  79.  
  80.     if (sockFD >= 0) {
  81.     close(sockFD);
  82.     sockFD = -1;
  83.     }
  84.     if (filePtr != NULL && filePtr != stdout) {
  85.     fclose(filePtr);
  86.     filePtr = NULL;
  87.     }
  88.     printf("\n");
  89.     longjmp(env, 1);
  90. }
  91.  
  92.  
  93. /*
  94.  *******************************************************************************
  95.  *
  96.  *  Malloc --
  97.  *  Calloc --
  98.  *
  99.  *      Calls the malloc library routine with SIGINT blocked to prevent
  100.  *    corruption of malloc's data structures. We need to do this because 
  101.  *    a control-C doesn't kill the program -- it causes a return to the 
  102.  *    main command loop.
  103.  *
  104.  *    NOTE: This method doesn't prevent the pointer returned by malloc 
  105.  *    from getting lost, so it is possible to get "core leaks".
  106.  *
  107.  *    If malloc fails, the program exits.
  108.  *
  109.  *  Results:
  110.  *    (address)    - address of new buffer.
  111.  *
  112.  *******************************************************************************
  113.  */
  114.  
  115. char *
  116. Malloc(size)
  117.     int size;
  118. {
  119.     char     *ptr;
  120.     int     saveMask;
  121.     extern char *malloc();
  122.  
  123. #ifdef SYSV
  124.     sighold(SIGINT);
  125.     ptr = malloc((unsigned) size);
  126.     sigrelse(SIGINT);
  127. #else
  128.     saveMask = sigblock(sigmask(SIGINT));
  129.     ptr = malloc((unsigned) size);
  130.     (void) sigsetmask(saveMask);
  131. #endif SYSV
  132.     if (ptr == NULL) {
  133.     fflush(stdout);
  134.     fprintf(stderr, "malloc failed\n");
  135.     fflush(stderr);
  136.     abort();
  137.     /*NOTREACHED*/
  138.     } else {
  139.     return(ptr);
  140.     }
  141. }
  142.  
  143. char *
  144. Calloc(num, size)
  145.     register int num, size;
  146. {
  147.     char *ptr = Malloc(num*size);
  148.     bzero(ptr, num*size);
  149.     return(ptr);
  150. }
  151.  
  152.  
  153. /*
  154.  *******************************************************************************
  155.  *
  156.  *  PrintHostInfo --
  157.  *
  158.  *    Prints out the HostInfo structure for a host.
  159.  *
  160.  *******************************************************************************
  161.  */
  162.  
  163. void
  164. PrintHostInfo(file, title, hp)
  165.     FILE     *file;
  166.     char     *title;
  167.     register HostInfo *hp;
  168. {
  169.     register char         **cp;
  170.     register ServerInfo     **sp;
  171.     char             comma;
  172.     int              i;
  173.  
  174.     fprintf(file, "%-7s  %s", title, hp->name);
  175.  
  176.     if (hp->addrList != NULL) {
  177.         if (hp->addrList[1] != NULL) {
  178.         fprintf(file, "\nAddresses:");
  179.         } else {
  180.         fprintf(file, "\nAddress:");
  181.         }
  182.         comma = ' ';
  183.         i = 0;
  184.         for (cp = hp->addrList; cp && *cp; cp++) {
  185.         i++;
  186.         if (i > 4) {
  187.             fprintf(file, "\n\t");
  188.             comma = ' ';
  189.             i = 0;
  190.         }
  191.         fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
  192.         comma = ',';
  193.         }
  194.     }
  195.  
  196.     if (hp->aliases != NULL) {
  197.         fprintf(file, "\nAliases:");
  198.         comma = ' ';
  199.         i = 10;
  200.         for (cp = hp->aliases; cp && *cp && **cp; cp++) {
  201.         i += strlen(*cp) + 2;
  202.         if (i > 75) {
  203.             fprintf(file, "\n\t");
  204.             comma = ' ';
  205.             i = 10;
  206.         }
  207.         fprintf(file, "%c %s", comma, *cp);
  208.         comma = ',';
  209.         }
  210.     }
  211.  
  212.     if (hp->servers != NULL) {
  213.         fprintf(file, "\nServed by:\n");
  214.         for (sp = hp->servers; *sp != NULL ; sp++) {
  215.  
  216.         fprintf(file, "- %s\n\t",  (*sp)->name);
  217.  
  218.         comma = ' ';
  219.         i = 0;
  220.         for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) {
  221.             i++;
  222.             if (i > 4) {
  223.             fprintf(file, "\n\t");
  224.             comma = ' ';
  225.             i = 0;
  226.             }
  227.             fprintf(file, 
  228.             "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
  229.             comma = ',';
  230.         }
  231.         fprintf(file, "\n\t");
  232.  
  233.         comma = ' ';
  234.         i = 10;
  235.         for (cp = (*sp)->domains; cp && *cp && **cp; cp++) {
  236.             i += strlen(*cp) + 2;
  237.             if (i > 75) {
  238.             fprintf(file, "\n\t");
  239.             comma = ' ';
  240.             i = 10;
  241.             }
  242.             fprintf(file, "%c %s", comma, *cp);
  243.             comma = ',';
  244.         }
  245.         fprintf(file, "\n");
  246.         }
  247.     }
  248.  
  249.     fprintf(file, "\n\n");
  250. }
  251.  
  252. /*
  253.  *******************************************************************************
  254.  *
  255.  *  OpenFile --
  256.  *
  257.  *    Parses a command string for a file name and opens
  258.  *    the file.
  259.  *
  260.  *  Results:
  261.  *    file pointer    - the open was successful.
  262.  *    NULL        - there was an error opening the file or
  263.  *              the input string was invalid.
  264.  *
  265.  *******************************************************************************
  266.  */
  267.  
  268. FILE *
  269. OpenFile(string, file)
  270.     char *string;
  271.     char *file;
  272. {
  273.     char     *redirect;
  274.     FILE     *tmpPtr;
  275.  
  276.     /*
  277.      *  Open an output file if we see '>' or >>'.
  278.      *  Check for overwrite (">") or concatenation (">>").
  279.      */
  280.  
  281.     redirect = index(string, '>');
  282.     if (redirect == NULL) {
  283.         return(NULL);
  284.     }
  285.     if (redirect[1] == '>') {
  286.         sscanf(redirect, ">> %s", file);
  287.         tmpPtr = fopen(file, "a+");
  288.     } else {
  289.         sscanf(redirect, "> %s", file);
  290.         tmpPtr = fopen(file, "w");
  291.     }
  292.  
  293.     if (tmpPtr != NULL) {
  294.         redirect[0] = '\0';
  295.     }
  296.  
  297.     return(tmpPtr);
  298. }
  299.  
  300. /*
  301.  *******************************************************************************
  302.  *
  303.  *  DecodeError --
  304.  *
  305.  *    Converts an error code into a character string.
  306.  *
  307.  *******************************************************************************
  308.  */
  309.  
  310. char *
  311. DecodeError(result)
  312.     int result;
  313. {
  314.     switch(result) {
  315.         case NOERROR:     return("Success"); break;
  316.         case FORMERR:    return("Format error"); break;
  317.         case SERVFAIL:    return("Server failed"); break;
  318.         case NXDOMAIN:    return("Non-existent domain"); break;
  319.         case NOTIMP:    return("Not implemented"); break;
  320.         case REFUSED:    return("Query refused"); break;
  321.         case NOCHANGE:    return("No change"); break;
  322.         case NO_INFO:     return("No information"); break;
  323.         case ERROR:     return("Unspecified error"); break;
  324.         case TIME_OUT:     return("Timed out"); break;
  325.         case NONAUTH:     return("Non-authoritative answer"); break;
  326.         default:         break;
  327.     }
  328.     return("BAD ERROR VALUE"); 
  329. }
  330.  
  331. int
  332. StringToClass(class, dflt)
  333.     char *class;
  334.     int dflt;
  335. {
  336.     if (strcasecmp(class, "IN") == 0)
  337.         return(C_IN);
  338.     if (strcasecmp(class, "CHAOS") == 0)
  339.         return(C_CHAOS);
  340.     if (strcasecmp(class, "ANY") == 0)
  341.         return(C_ANY);
  342.     fprintf(stderr, "unknown query class: %s\n", class);
  343.     return(dflt);
  344. }
  345. /*
  346.  *******************************************************************************
  347.  *
  348.  *  StringToType --
  349.  *
  350.  *    Converts a string form of a query type name to its 
  351.  *    corresponding integer value.
  352.  *
  353.  *******************************************************************************
  354.  */
  355.  
  356. int
  357. StringToType(type, dflt)
  358.     char *type;
  359.     int dflt;
  360. {
  361.     if (strcasecmp(type, "A") == 0)
  362.         return(T_A);
  363.     if (strcasecmp(type, "NS") == 0)
  364.         return(T_NS);            /* authoritative server */
  365.     if (strcasecmp(type, "MX") == 0)
  366.         return(T_MX);            /* mail exchanger */
  367.     if (strcasecmp(type, "CNAME") == 0)
  368.         return(T_CNAME);        /* canonical name */
  369.     if (strcasecmp(type, "SOA") == 0)
  370.         return(T_SOA);            /* start of authority zone */
  371.     if (strcasecmp(type, "MB") == 0)
  372.         return(T_MB);            /* mailbox domain name */
  373.     if (strcasecmp(type, "MG") == 0)
  374.         return(T_MG);            /* mail group member */
  375.     if (strcasecmp(type, "MR") == 0)
  376.         return(T_MR);            /* mail rename name */
  377.     if (strcasecmp(type, "WKS") == 0)
  378.         return(T_WKS);            /* well known service */
  379.     if (strcasecmp(type, "PTR") == 0)
  380.         return(T_PTR);            /* domain name pointer */
  381.     if (strcasecmp(type, "HINFO") == 0)
  382.         return(T_HINFO);        /* host information */
  383.     if (strcasecmp(type, "MINFO") == 0)
  384.         return(T_MINFO);        /* mailbox information */
  385.     if (strcasecmp(type, "AXFR") == 0)
  386.         return(T_AXFR);            /* zone transfer */
  387.     if (strcasecmp(type, "MAILB") == 0)
  388.         return(T_MAILB);        /* mail box */
  389.     if (strcasecmp(type, "ANY") == 0)
  390.         return(T_ANY);            /* matches any type */
  391.     if (strcasecmp(type, "UINFO") == 0)
  392.         return(T_UINFO);        /* user info */
  393.     if (strcasecmp(type, "UID") == 0)
  394.         return(T_UID);            /* user id */
  395.     if (strcasecmp(type, "GID") == 0)
  396.         return(T_GID);            /* group id */
  397.     fprintf(stderr, "unknown query type: %s\n", type);
  398.     return(dflt);
  399. }
  400.  
  401. /*
  402.  *******************************************************************************
  403.  *
  404.  *  DecodeType --
  405.  *
  406.  *    Converts a query type to a descriptive name.
  407.  *    (A more verbose form of p_type.)
  408.  *
  409.  *
  410.  *******************************************************************************
  411.  */
  412.  
  413. static  char nbuf[20];
  414.  
  415. char *
  416. DecodeType(type)
  417.     int type;
  418. {
  419.     switch (type) {
  420.     case T_A:
  421.         return("address");
  422.     case T_NS:
  423.         return("name server");
  424.     case T_MX:        
  425.         return("mail exchanger");
  426.     case T_CNAME:        
  427.         return("cannonical name");
  428.     case T_SOA:        
  429.         return("start of authority zone");
  430.     case T_MB:        
  431.         return("mailbox domain name");
  432.     case T_MG:        
  433.         return("mail group member");
  434.     case T_MR:        
  435.         return("mail rename name");
  436.     case T_NULL:        
  437.         return("null resource record");
  438.     case T_WKS:        
  439.         return("well known service");
  440.     case T_PTR:        
  441.         return("domain name pointer");
  442.     case T_HINFO:        
  443.         return("host");
  444.     case T_MINFO:        
  445.         return("mailbox (MINFO)");
  446.     case T_AXFR:        
  447.         return("zone transfer");
  448.     case T_MAILB:        
  449.         return("mail box");
  450.     case T_ANY:        
  451.         return("any type");
  452.     case T_UINFO:
  453.         return("user info");
  454.     case T_UID:
  455.         return("user id");
  456.     case T_GID:
  457.         return("group id");
  458.     default:
  459.         (void) sprintf(nbuf, "%d", type);
  460.         return (nbuf);
  461.     }
  462. }
  463.